import info.gridworld.actor.Actor;
import info.gridworld.actor.Bug;
import info.gridworld.actor.Flower;
import info.gridworld.grid.Grid;
import info.gridworld.grid.Location;

import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Stack;

public class MazeBugPro  extends Bug {
    Stack<Location> Path; //栈记录可行方案的路
    // 虫子走过的路会留下花 可以帮助我们判断该路是否走过
    // 或者我们这里额外加一个HashMap来帮我们记录该路是否走过
    HashMap<Location,Boolean> Record; //记录走过的路的可行性 true可行

    Boolean isEnd = false; //记录是否结束的状态

    private final int[] dir = { Location.EAST, Location.SOUTH, Location.WEST, Location.NORTH}; // 0右 1下 2左 3上
    private int[] isval = {1,1,1,1}; //对应 右下左上 1为可行 0为不可行
    //pro部分 start
    private int[] dirT = {0,0,0,0}; //对应 右下左上 行走过的次数
    //pro部分 end

    public MazeBugPro()
    {
        setColor(Color.orange);
        Path = new Stack<>();
        Record = new HashMap<>();

    }

    /**
     * Constructs a bug of a given color.
     * @param bugColor the color for this bug
     */
    public MazeBugPro(Color bugColor)
    {
        setColor(bugColor);
        Path = new Stack<>();
        Record = new HashMap<>();
    }

    /**
     * Moves if it can move, turns otherwise.
     */
    public void act()
    {
        if (isEnd)
            return;
        if (canMove()) {
            turn();
            move();
        } else{
            if (isEnd)
                return;
            goBack();
        }


    }

    /**
     * Turns the bug 45 degrees to the right without changing its location.
     */
    //根据概率选择方向
    public void turn()
    {
        //pro部分 start
        ArrayList<Integer> ind = new ArrayList<Integer>();
        ArrayList<Integer> val = new ArrayList<Integer>();
        for (int i=0;i<4;i++){
            if (isval[i]==1){
                ind.add(i);
                val.add(dirT[i]);
            }
        }
        if (ind.isEmpty())
            return;
        int indexOfMaxElement = val.indexOf(Collections.max(val));
        int index = ind.get(indexOfMaxElement);
        setDirection(dir[index]);
        dirT[index]++;
        //pro部分 end

//        //debug
//        for (int i=0;i<4;i++){
//            System.out.print(dirT[i]+" ");
//        }
//        System.out.println();

    }

    /**
     * Moves the bug forward, putting a flower into the location it previously
     * occupied.
     */

    public void move()
    {
        Grid<Actor> gr = getGrid();
        if (gr == null)
            return;
        Location loc = getLocation();
        Location next = loc.getAdjacentLocation(getDirection());
        if (gr.get(next) instanceof Flag) {
            System.out.println("End");
            isEnd = true;
            moveTo(next);
        }

        if(!isEnd) {
            moveTo(next);
            Path.add(loc);
            Record.put(loc, false);
        }

        // 保留花花 显示路径 及 辅助判断是否走过
        Flower flower = new Flower(getColor());
        flower.putSelfInGrid(gr, loc);
    }


    // 如果有可以走的方向就返回true
    public boolean canMove()
    {
        Grid<Actor> gr = getGrid();
        if (gr == null)
            return false;
        Location loc = getLocation();

        int cnt = 0 ;
        for(int i=0;i<4;i++){
            Location neighborloc = loc.getAdjacentLocation(dir[i]);
            if (gr.isValid(neighborloc)){
                if (gr.get(neighborloc) == null){
                    isval[i] = 1;
                    cnt++;
                }
                else if(gr.get(neighborloc) instanceof Flower) {
                    if (Record.get(neighborloc)){
                        isval[i] = 1;
                        cnt++;
                    }
                    else
                        isval[i] = 0;
                }
                else if (gr.get(neighborloc) instanceof Flag) {
                    isval[i] = 1;
                    cnt++;
                }
                else {
                    isval[i] = 0;
                }
            }
            else {
                isval[i] = 0;
            }
        }


        return cnt > 0;


    }

    public void goBack(){
        Grid<Actor> gr = getGrid();
        Location loc = getLocation();
        setDirection(loc.getDirectionToward(Path.peek()));
        moveTo(Path.peek());
        Record.put(loc, false);
        Path.pop();


        Flower flower = new Flower(getColor());
        flower.putSelfInGrid(gr, loc);

        //pro部分 start 这个要不要算呢？
//        int direct = loc.getDirectionToward(Path.peek());
//        setDirection(direct);
//        for (int i=0;i<4;i++){
//            if (direct == dir[i]) {
//                dirT[i]++;
//                break;
//            }
//        }
        //pro部分 end

    }
}

